package cn.ococci.dm.Main.Fragment;

import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

import cn.ococci.dm.Base.BaseApp;
import cn.ococci.dm.Base.BaseFragment;
import cn.ococci.dm.Main.Adapter.SelectedFloorAdapter;
import cn.ococci.dm.Main.Const;
import cn.ococci.dm.Main.Core.CommandOpenInfrared;
import cn.ococci.dm.Main.Core.CommandStatusCallback;
import cn.ococci.dm.Main.Core.CommandType;
import cn.ococci.dm.Main.Core.OtaVersionCommand;
import cn.ococci.dm.Main.Core.SocketCommand;
import cn.ococci.dm.Main.Core.UpGradeCommand;
import cn.ococci.dm.Main.Core.WhiteCommand;
import cn.ococci.dm.Main.DataBuilder;
import cn.ococci.dm.Main.Model.DoorModel;
import cn.ococci.dm.Main.Model.Ota;
import cn.ococci.dm.Main.Model.UnitModel;
import cn.ococci.dm.Main.OtaType;
import cn.ococci.dm.Main.Tools.DbTool;
import cn.ococci.dm.Main.Tools.DialogTool;
import cn.ococci.dm.Main.Tools.LogTool;
import cn.ococci.dm.Main.Tools.SpTool;
import cn.ococci.dm.Main.Tools.StringTool;
import cn.ococci.dm.Main.Tools.ThreadTool;
import cn.ococci.dm.Main.Tools.ToastTool;
import cn.ococci.dm.Main.View.Dialog.DialogAdapter;
import cn.ococci.dm.Main.View.OTAUpgradeView;
import cn.ococci.dm.Main.View.SwitchButton;
import cn.ococci.dm.Main.View.WebProgress;
import cn.ococci.dm.WiFi.NetWorkStateBroadcastReceiver;
import cn.ococci.dm.WiFi.WifiOperate;
import cn.ococci_dm.R;

/**
 * Created by cyan on 16/1/15.
 * 建立门禁系统连接并设置楼栋单元列表
 */
public class BridgingDoorFragment extends BaseFragment {

    private final String TAG = BridgingDoorFragment.class.getSimpleName();

    private ListView selectedFloorLv;
    private Button bridgeBtn;
    private OTAUpgradeView otaUpgradeView;

    private List<UnitModel> selectedFloorList;
    private DoorModel curDoor;
    private ScanResult curScanResult;

    private SelectedFloorAdapter selectUnitAdapter;
    private WifiOperate operate;

    private boolean[] isUpgrades = new boolean[2];
    private Ota[] otaList = new Ota[2];

    private NetWorkStateBroadcastReceiver netWorkReceiver;

    private UpGradeCommand upGradeCommand;

    private boolean canConnect = true;
    private SwitchButton switchButton;

    @Override
    protected int getResId() {
        return R.layout.fragment_bridg_door;
    }

    @Override
    protected void initView(View parent) {

        selectedFloorLv = (ListView) parent.findViewById(R.id.selectedFloorLv);
        bridgeBtn = (Button)parent.findViewById(R.id.bridgeBtn);
        switchButton = (SwitchButton) parent.findViewById(R.id.infraredSwitchButton);
        otaUpgradeView = (OTAUpgradeView)parent.findViewById(R.id.otaUpgradeView);
    }

    @Override
    protected void initData() {

        switchButton.setChecked(SpTool.getBoolean(Const.open_infrared,false));

        operate = new WifiOperate(getActivity());
        selectedFloorList = new ArrayList<>();

        compareOtaVersion();
    }

    private void compareOtaVersion(){

        SocketCommand socketCommand = new SocketCommand(new CommandStatusCallback() {
            @Override
            public void successForOtaVersion(final String[] versions) {
                // with DB Compare
                otaList[0] = DbTool.findOTA(OtaType.OTC_AP.ordinal());
                otaList[1] = DbTool.findOTA(OtaType.OTC_PR.ordinal());

                isUpgrades[0] = StringTool.compareVersion(otaList[0].getVersion(),versions[0]);
                isUpgrades[1] = StringTool.compareVersion(otaList[1].getVersion(),versions[1]);

                ThreadTool.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(isUpgrades[0] || isUpgrades[1]){
                            otaUpgradeView.showUpgradeView();
                            otaUpgradeView.initUpgradeView(versions,otaList);
                        }else{
                            otaUpgradeView.hiddenUpgradeView();
                        }
                    }
                });

            }
        });

        OtaVersionCommand otaVersionCommand = new OtaVersionCommand(socketCommand);
        otaVersionCommand.execute();

    }


    @Override
    public void initBackData() {

        if(selectUnitAdapter == null){
            initAdapter();
        }else{
            selectUnitAdapter.notifyDataSetChanged();
        }

    }


    @Override
    protected void initAdapter() {

        selectUnitAdapter = new SelectedFloorAdapter(getActivity(), selectedFloorList, new SelectedFloorAdapter.OperatorFloor() {
            @Override
            public void addFloor() {
                turnTo(new ChoseFloorFragment().setYetSelectList(selectedFloorList));
            }

            @Override
            public void deleteFloor(int pos) {
                selectedFloorList.remove(pos);
            }
        },selectedFloorLv);

    }


    private void handlerInfraredStatus(){

        SocketCommand statusCommand = new SocketCommand(new CommandStatusCallback() {
            @Override
            public void successForInfrared(final boolean status) {
                    ThreadTool.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            switchButton.setChecked(status);
                        }
                    });
            }
        });

        CommandOpenInfrared commandOpenInfrared = new CommandOpenInfrared(statusCommand, CommandType.INFRARED_STATUS);
        commandOpenInfrared.execute();

    }



    @Override
    protected void initListener() {

        switchButton.setChangeListener(new SwitchButton.ChangeStateListener() {
            @Override
            public void onChangeState(final boolean checkState) {

                SocketCommand socketCommand = new SocketCommand(new CommandStatusCallback() {
                    @Override
                    public void successExecuteCommand() {
                        SpTool.putBoolean(Const.open_infrared,checkState);
                        switchButton.setChecked(checkState);

                    }
                });

                CommandOpenInfrared commandOpenInfrared = new CommandOpenInfrared(socketCommand,checkState);
                commandOpenInfrared.execute();

            }

            @Override
            public void onChangeState(int id, boolean checkState) {

            }
        });


        bridgeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(!StringTool.hasData(selectedFloorList)){
                    ToastTool.show(R.string.modify_bridge_no_chose_data);
                    return;
                }

                if(!operate.isWifiConnected()){
                    ToastTool.show(R.string.net_from_keep_wifi_unimpeded);
                    return;
                }

                if(!curDoor.getWifiBssid().equals(operate.returnWifiBSsId())){
                    ToastTool.show(BaseApp.findResIdDecoderString(R.string.self_auto_connected)+ curDoor.getWifiName());
                    return;
                }

                bridgeCommand();
            }
        });

        // OTA 升级操作
        otaUpgradeView.setOtaOperator(new OTAUpgradeView.OtaOperator() {
            @Override
            public void clickUpgrade() {

                if(operate.isClose() || (curScanResult != null  &&
                        !operate.returnWifiBSsId().equals( StringTool.replaceDoubleQuotationMarks(curScanResult.BSSID)))){
                    ToastTool.show(R.string.upgrade_net_error);
                    return;
                }

                if(isUpgrades[1]){
                    upgradeWithOtaCommand(OtaType.OTC_PR);
                }else {
                    upgradeWithOtaCommand(OtaType.OTC_AP);
                }
            }
        });

    }

    private void upgradeWithOtaCommand(final OtaType type){

        if(WebProgress.inValidInstance()){
            WebProgress.createDialog(getActivity(), new Runnable() {
                @Override
                public void run() {
                    LogTool.log(TAG," dismiss dialog");
                    if(upGradeCommand != null){
                        upGradeCommand.breakLoop();

                    }
                }
            });
            WebProgress.setLoadingStr(R.string.upgrading);
        }

        String ip = operate.getNetworkIp();
        if(upGradeCommand == null){
            upGradeCommand =  new UpGradeCommand();
        }

        upGradeCommand.initUpGradeCommand(type,ip, new UpGradeCommand.UpgradeCompletedListener() {
            @Override
            public void onUpgradeError(final String errorMsg) {
                ThreadTool.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(upGradeCommand != null){
                            upGradeCommand.breakLoop();

                        }
                        WebProgress.webDismiss();
                        ToastTool.show(errorMsg);
                    }
                });
            }

            @Override
            public void onStartListener() {
                LogTool.log(TAG,"开始传输OTA升级文件...");
            }

            @Override
            public void onCompletedListener(boolean success, OtaType type) {
                if(success){
                    upgradeSuccess(type);
                }else {
                    upgradeFailure(type);
                }
            }
        });


    }


    private void upgradeFailure(final OtaType type){
        WebProgress.webDismiss();
        DialogTool.createMaterialDialog(getActivity(), new DialogAdapter() {
            @Override
            public boolean confirm() {
                upgradeWithOtaCommand(type);
                return super.confirm();
            }

            @Override
            public int getCaptionResId() {
                return R.string.update_otc_title;
            }

            @Override
            public int getMsgResId() {
                return R.string.ota_upgrade_dialog_msg;
            }

            @Override
            public CharSequence[] btnNames() {
                return BaseApp.findResIdDecoderArray(R.array.upgrade_title);
            }
        });

    }

    // successType? no:next(ExecuteUpgrade) -> save data -> （when ap dis wifi）refresh view
    // loop check version
    private void upgradeSuccess(final OtaType type){

        initNetworkStatus();
        SocketCommand socketCommand = new SocketCommand(new CommandStatusCallback() {
            @Override
            public void successForSingleOtaVersion(String version) {
                isUpgrades[type.ordinal()-1] = false;
                Ota ota = DbTool.findOTA(type.ordinal());
                ota.setVersion(version);
                ota.update(ota.getId());

                if(type == OtaType.OTC_PR && isUpgrades[0]){
                    otaUpgradeView.hiddenPRVersionStatus(version);
                    SystemClock.sleep(100);
                    LogTool.log(TAG,"开始升级 OTA--PR...");
                    upgradeWithOtaCommand(OtaType.OTC_AP);
                }

                if(!isUpgrades[0] && !isUpgrades[1]){
                    ThreadTool.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            WebProgress.webDismiss();
                            ToastTool.show(R.string.set_success);
                            otaUpgradeView.hiddenUpgradeView();
                        }
                    });
                }

            }

        });

        String newVersion = otaList[type == OtaType.OTC_AP?0:1].getVersion();
        OtaVersionCommand otaVersionCommand = new OtaVersionCommand(socketCommand,type,newVersion);
        otaVersionCommand.execute();
    }

    private void initNetworkStatus() {
        netWorkReceiver = new NetWorkStateBroadcastReceiver(new NetWorkStateBroadcastReceiver.NetWorkStateListener() {
            @Override
            public void onNetWorkWithWifConnected(String BSSid) {

                if(StringTool.isEmpty(BSSid)){
                    return;
                }

                if(curScanResult != null ||StringTool.isEmpty(curScanResult.BSSID)){
                    return;
                }

                if(!BSSid.equals(curScanResult.BSSID)){

                    if(upGradeCommand == null || !canConnect){
                        return;
                    }

                    canConnect = false;
                    if(isUpgrades[1]){
                        autoConnecting(OtaType.OTC_PR);
                    }else if(isUpgrades[0]){
                        autoConnecting(OtaType.OTC_AP);
                    }
                }
            }
            @Override
            public void onNetworkDisconnected() {}
        });

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(NetWorkStateBroadcastReceiver.ACTION_NETWORK_STATUS_CHANGE);
        intentFilter.addAction(NetWorkStateBroadcastReceiver.ACTION_NETWORK_STATUS_CHANGE_ETHERNET);
        intentFilter.addAction(NetWorkStateBroadcastReceiver.ACTION_NETWORK_STATUS);
        getActivity().registerReceiver(netWorkReceiver, intentFilter);
    }


    private void bridgeCommand(){

        List<Integer> list = new ArrayList<>();
        for (UnitModel unitModel:selectedFloorList){
            list.add(unitModel.getUnitCode());
        }

        SocketCommand socketCommand = new SocketCommand(new CommandStatusCallback() {
            @Override
            public void startExecuteCommand() {
                LogTool.log(TAG,"开始连接");
            }

            @Override
            public void successExecuteCommand() {
                 LogTool.log(TAG,"执行命令成功");
                ToastTool.showOnUiThread(R.string.set_success);
                curDoor.setDoorMac(operate.returnWifiBSsId());
                DataBuilder.builderDataWithSaveToDb(curDoor,selectedFloorList);
            }

            @Override
            public void failureExecuteCommand() {
                LogTool.log(TAG,"执行命令失败");
            }

        });

        WhiteCommand command = new WhiteCommand(list,socketCommand);
        command.execute();
    }


    private void autoConnecting(final OtaType type){

        if(curScanResult == null){
            ToastTool.showOnUiThread(R.string.self_auto_connected);
            return;
        }

        if(operate.isClose()){
            operate.isOpen();
        }

        operate.autConnected(curScanResult, new WifiOperate.ActionListener() {
            @Override
            public void onFinished(boolean success) {
                canConnect = true;
                if(success){
                    upgradeSuccess(type);
                }
            }
        });

    }


    @Override
    public String getCaption() {
        return BaseApp.findResIdDecoderString(R.string.modify_bridge_title);
    }

    @Override
    public boolean goBack() {

        if(upGradeCommand != null){
            upGradeCommand.breakLoop();
            upGradeCommand = null;
        }
        onDestroyReceiver();

        return super.goBack();
    }

    public BridgingDoorFragment setDoor(DoorModel door){

        curDoor =  door ;
        return this;
    }

    public BridgingDoorFragment setScanResult(ScanResult curScanResult){

        this.curScanResult = curScanResult;
        return this;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onDestroyReceiver();
    }

    private void onDestroyReceiver(){

        if(netWorkReceiver != null){
            getActivity().unregisterReceiver(netWorkReceiver);
            netWorkReceiver = null;
        }

    }
}
